<?php

/*
 *	Autoloader class
 *
 *	@extends Kernel
 *	@final
 */
final class Autoload extends Kernel
{
	/*
	 *	@paths	array	Paths to search for files
	 *
	 *	@protected
	 */
	protected $paths = array();
	
	/*
	 *	@files	array	Included (checked) files 
	 */
	protected $files = array();
	
	/*
	 *	Constructor
	 *
	 *	Register SPL autoload
	 */
	public function __construct()
	{
		spl_autoload_register(array($this, 'load'));
	}
	
	/*
	 *	Add directory for files searching
	 *
	 *	@param	string	Absolute path
	 *
	 *	@throw
	 */
	public function add()
	{
		$paths = func_get_args();
		
		foreach($paths as $path)
		{
			$path = BASE.DS.$path;
			
			if(!is_dir($path))
			{
				throw new Exception(__CLASS__.': Directory "'.$path.'" does not exists');
			}
			
			if(isset($this->paths[$path]))
			{
				throw new Exception(__CLASS__.': Directory "'.$path.'" already included');
			}
			
			$path = rtrim($path, '/\\');
			
			array_push($this->paths, $path);
		}
	}
	
	/*
	 *	Load file
	 *
	 *	@param	string	File name
	 *	@param	string	Path to file [optional]
	 *	@return	boolean
	 */
	public function load($name)
	{
		$name = strtolower($name);
		
		// <shitcode>
		/*
		 *	Sometimes i hate myself :'(
		 */
		$name = explode('\\', $name);
		$name = array_reverse($name);
		$name = $name[0];
		// </shitcode>
		
		foreach($this->paths as $path)
		{
			$file = $path.DS.$name.EXT;
			
			if(key_exists($file, $this->paths))
			{
				continue;
			}
			
			$this->files[$file] = false;
			
			if(is_file($file))
			{
				$this->files[$file] = true;
				
				require_once $file;
			}
		}
	}
	
	/*
	 *	Scan directory (and subfolder) and complete the paths
	 *
	 *	@todo	Add caching
	 *	@param	string	Directory for scaning
	 */
	public function scan($dir)
	{
		$dirs = array_diff(scandir($dir), array('.', '..'));
		
		foreach($dirs as $dy)
		{ 
			if(is_dir($dir.'/'.$dy) && substr($dy, 0, 1) != '.')
			{
				$this->addPath($dir.'/'.$dy);
				
				$this->scan($dir.'/'.$dy); 
			}
        	else
        	{
        		continue;
        	}
		}
	}
	
	/*
	 *	Destructor
	 *
	 *	Unregister SPL autoload
	 */
	public function __destruct()
	{
		spl_autoload_unregister(array($this, 'load'));
	}
}